package com.stock.calculator;

public class StockCalculator {
    private static final double EARNINGS_PRICE_TIMES_MAX   = 15;
    private static final double BOOK_VALUE_PRICE_TIMES_MAX = 1.5;
    private static final double INTRINSIC_VALUE_PRICE_TIME_MIN = 1.5;

    public static double calcEarningPrice(double earningsPerShare) {
        return earningsPerShare * EARNINGS_PRICE_TIMES_MAX;
    }

    public static double calcEarningPrice(String earningsPerShare) {
        return calcEarningPrice(Double.parseDouble(earningsPerShare));
    }

    public static double calcBookValuePrice(double currentBookValue) {
        return currentBookValue * BOOK_VALUE_PRICE_TIMES_MAX;
    }

    public static double calcBookValuePrice(String currentBookValue) {
        return calcBookValuePrice(Double.parseDouble(currentBookValue));
    }

    public static double calcEarningAndBookValuePrice(double earningsPerShare, double currentBookValue) {
        return Math.pow(calcEarningPrice(earningsPerShare) * calcBookValuePrice(currentBookValue), 0.5);
    }

    public static double calcEarningAndBookValuePrice(String earningsPerShare, String currentBookValue) {
        return calcEarningAndBookValuePrice(Double.parseDouble(earningsPerShare), Double.parseDouble(currentBookValue));
    }

    public static double calcIntrinsicValue(double dividend, double currentBookValue, double bookValueGrowthRate,
            int years, double tenYrFederalNoteRate) {
        double futureBookValue = currentBookValue * Math.pow(1 + bookValueGrowthRate / 100, years);

        double futureFederalNoteValue = Math.pow(1 + tenYrFederalNoteRate / 100, years);

        double part1 = dividend * (1 - 1 / futureFederalNoteValue) / tenYrFederalNoteRate * 100;
        double part2 = futureBookValue / futureFederalNoteValue;

        return part1 + part2;
    }

    public static double calcBargainValue(String intrinsicValue) {
        return calcBargainValue(Double.parseDouble(intrinsicValue));
    }

    public static double calcBargainValue(double intrinsicValue) {
        return intrinsicValue / INTRINSIC_VALUE_PRICE_TIME_MIN;
    }

    public static Double[] calcGrowthRate(String[] bookValues) {
        double[] bookValues_double = new double[bookValues.length];

        for (int i = 0; i < bookValues.length; ++i)
            bookValues_double[i] = Double.parseDouble(bookValues[i]);

        return calcGrowthRate(bookValues_double);
    }

    public static Double[] calcGrowthRate(double[] bookValues) {

        Double[] growthRates = new Double[bookValues.length];
        for (int i = 0; ++i < bookValues.length;) {
            growthRates[i] = calcGrowthRate(bookValues[i - 1], bookValues[i], 1);
        }
        growthRates[0] = calcGrowthRate(bookValues[0], bookValues[bookValues.length - 1], bookValues.length - 1);
        return growthRates;
    }

    public static double calcGrowthRate(double endValue, double startValue, int years) {
        return 100 * (Math.pow(endValue / startValue, 1.0 / years) - 1);
    }

}
